using System;
using System.Data;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using CI = ClearImage;

using ImageGear.Core;
using ImageGear.Formats;
using ImageGear.Formats.PDF;
using ImageGear.Processing;
using ImageGear.Display;

using ImageGear.Recognition;
using ImageGear.ART;

namespace Dimok {
	public class BarCode {
		//			RecognizePageAsZone(ImGearRecFillingMethod.BARCODE, ImGearRecRecognitionModule.BAR);
		static BarCode() {
			ImGearLicense.SetSolutionName("Onrebate.com");
			ImGearLicense.SetSolutionKey(0x8150A590,0x51AAF581,0x6A5DB058,0x59A10F61);
			ImGearLicense.SetOEMLicenseKey("1.0.Ea2oGrYZxHIedefjv0hrkOG9dafyW9WBfjhDbmIjWaPHkmPekeYoFmYmPyWZFmbmIoF5keGHYO49q9vyxDFyWC4DkmFe4yk5FOboIZ4rx9q9G0PHFCW5fa4ahBkyqZYr20GeIBf0Febmd5dCGCFadodDYaxO49I5Prf5doI52RhHYBxa2DWCPeIrFmvahaGHGjfOb5Wmd9YjPCbBdObBhZh9b0hB4mIHfBkmxmI529faPjGrYm2Cq0fmYZkehaFeGBPmfBI5xZWDk5fo2mYCP9b5WOWrd9YmY5YCdCk5YHx5G5IZk9keqrxCGrdehChahmqHGBYZxDxe25qmbOhyy");
			//ImGearLicense.SetSolutionName("AccuSoft 3-40-2");
		}
		public static BarCodes.BarCodeDataTable Read(byte[] file) {
			return Read(ImGearFileFormats.LoadPage(new MemoryStream(file),0));
		}
		[MethodImplAttribute(MethodImplOptions.Synchronized)]
		public static BarCodes.BarCodeDataTable Read(ImGearPage page) {
			ImGearRecognition rec = new ImGearRecognition();		// Represents recognition engine
			ImGearRecPage recPage;		// Represents an image loaded into the recognition engine
			recPage = rec.ImportPage((ImGearRasterPage)page);
			ImGearRecZone z = new ImGearRecZone(ImGearRecFillingMethod.BARCODE,ImGearRecRecognitionModule.BAR);
			z.Rect = new ImGearRectangle(0,0,recPage.Image.Width,recPage.Image.Height);
			recPage.Zones.Add(z);
			recPage.RecognizeToMemory();
			rec.OutputManager.Format = "Rec ASCII (Standard)";
			string RDFilename = Path.GetTempFileName();
			recPage.WriteRecognitionData(RDFilename);
			try {
				rec.OutputManager.WriteDocument(RDFilename,".");
				BarCodes.BarCodeDataTable dt = new BarCodes().BarCode;
				foreach(string barCode in rec.OutputManager.OutputText.Split(Environment.NewLine.ToCharArray()))
					if( barCode != "") dt.AddBarCodeRow(barCode,0,"BarCode");
				return dt;
			} finally {
				recPage.Dispose();
				recPage = null;
				rec.Dispose();
				rec = null;
				File.Delete(RDFilename);
			}
		}
		public static BarCodes.BarCodeDataTable ReadCI(byte[] file) {
			string fileName = Path.GetTempFileName();
			File.WriteAllBytes(fileName,file);
			try {
				return Read(fileName);
			} finally { File.Delete(fileName); }
		}
		[MethodImplAttribute(MethodImplOptions.Synchronized)]
		public static BarCodes.BarCodeDataTable Read(string fileName) {
			ClearImage.CiServer CiServer = new ClearImage.CiServer();
			ClearImage.CiBarcodePro BcReader = null;
			try {
				BcReader = CiServer.CreateBarcodePro();
				BcReader.Image.Open(fileName,1);
#if false
	      // for faster reading specify only expected barcode types
				BcReader.AutoDetect1D = EBoolean.ciFalse; 
				BcReader.Type = FBarcodeType.cibfCode39 | FBarcodeType.cibfCode128; 
#else
				// Read all most popular barcode types
				BcReader.AutoDetect1D = CI.EBoolean.ciTrue;
#endif
				// for faster reading and if barcodes of good quality set to EBarcodeAlgorithm.cibBestSpeed
				BcReader.Algorithm = CI.EBarcodeAlgorithm.cibBestRecognition;
				// for faster reading specify only required direction
				BcReader.Directions = CI.FBarcodeDirections.cibHorz | CI.FBarcodeDirections.cibDiag | CI.FBarcodeDirections.cibVert;
				// for faster reading and if only one barcode expected call Find(1)
				long nBc = 0;
				///Op.Begin();
				nBc = BcReader.Find(0);
				///Op.Done();
				//DataTable dt = new DataSet().Tables.Add("BarCodes");
				BarCodes.BarCodeDataTable dt = new BarCodes.BarCodeDataTable();
				for(int i = 1; i <= nBc; i++)
					dt.AddBarCodeRow(BcReader.Barcodes[i].Text,(int)BcReader.Barcodes[i].Type,BcReader.Barcodes[i].Type + "");
				BcReader.Image.Close();
				return dt;
			}catch(Exception exc){
				throw new Exception("FileName:" + fileName,exc);
			} finally {
				if(BcReader != null) Marshal.ReleaseComObject(BcReader);
				if(CiServer != null) Marshal.ReleaseComObject(CiServer);
				System.GC.Collect();
				System.GC.WaitForPendingFinalizers();
			}
		}
	}
}
